package com.yiboshi.rehrs.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.yiboshi.rehrs.common.VarConstant;
import com.yiboshi.rehrs.config.ThreadLocalSession;
import com.yiboshi.rehrs.domain.entity.MyZhongUser;
import com.yiboshi.rehrs.domain.entity.SmZhongUser;
import com.yiboshi.rehrs.domain.entity.ZhongOrder;
import com.yiboshi.rehrs.domain.entity.ZhongUser;
import com.yiboshi.rehrs.domain.service.*;
import com.yiboshi.rehrs.exception.ZyantExceptionUtils;
import com.yiboshi.rehrs.feign.PosterFeign;
import com.yiboshi.rehrs.helper.HttpHelper;
import com.yiboshi.rehrs.helper.LimitHelper;
import com.yiboshi.rehrs.helper.ProxyHelper;
import com.yiboshi.rehrs.helper.RedisHelper;
import com.yiboshi.rehrs.manager.SmurfsManager;
import com.yiboshi.rehrs.param.Letter;
import com.yiboshi.rehrs.param.ZhongReq;
import com.yiboshi.rehrs.param.ZhongRes;
import com.yiboshi.rehrs.param.smurfs.PayInfo;
import com.yiboshi.rehrs.param.smurfs.Product;
import com.yiboshi.rehrs.util.*;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;


@RestController
@RequestMapping("/smf/member/")
@Slf4j
public class SmurfsMemberController {

    @Autowired
    RedisHelper redisHelper;

    @Autowired
    PosterFeign posterFeign;

    @Autowired
    HttpHelper httpHelper;

    @Autowired
    IZhongUserService zhongUserService;

    @Autowired
    IZhongUserImageService zhongUserImageService;

    @Autowired
    IInviteRecordService inviteRecordService;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Autowired
    ISystemConfigService systemConfigService;

    @Autowired
    SmurfsManager smurfsManager;

    @Autowired
    IZhongOrderService zhongOrderService;

    @Autowired
    LimitHelper limitHelper;

    @Autowired
    ProxyHelper proxyHelper;


    @ApiOperation(value = "1.0 info", httpMethod = "POST", notes = "1.0 info", consumes = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping("info")
    public ZhongRes memberInfo() {
        SmZhongUser smUserInfo = ThreadLocalSession.getSmUserInfo();//StrUtils.isNotBlank(account)?zhongUserService.getSmUser(account) :cached;
        if(smUserInfo==null){
            return VarConstant.need_login_res;
        }
        if(smUserInfo.getVipExpDate()!=null&&smUserInfo.getVipExpDate().isAfter(LocalDateTime.now())){
            String sAuth = limitHelper.getSAuth(smUserInfo.getUserCode(),1);
            smUserInfo.setVipAuth(sAuth);
            smUserInfo.setVipHost("");
        }else{
            //已到期
            smUserInfo.setVipExpDate(null);
        }
        smUserInfo.setToken("");
        return  ZhongRes.ok(smUserInfo);
    }

    @ApiOperation(value = "2.1 使用邀请码", httpMethod = "POST", notes = "2.1 使用邀请码", consumes = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping("invite")
    public ZhongRes<ZhongUser> recharge(@RequestBody() ZhongReq zhongReq) {

        ZhongUser zhongUser = redisHelper.loadSessionUser(null,true);
        if (zhongUser==null) {
            return VarConstant.need_login_res;
        }
        String card = zhongReq.getCard();
        if(StrUtils.isBlank(card)){
            return ZhongRes.fail("");
        }
        ZhongRes<ZhongUser> zhongUserZhongRes = null;
        if(card.length()==9&&zhongUser.getMode()==1){
            //邀请福利发放
            zhongUserZhongRes = invite(zhongReq,zhongUser);
        }else {
            return ZhongRes.fail("");
        }
        return zhongUserZhongRes;
//        ZhongUser obj = zhongUserZhongRes.getObj();
//        if(!zhongUserZhongRes.isOK()){
//            return zhongUserZhongRes;
//        }
        //String sAuth = limitHelper.getSAuth(obj.getAccount());
        //SmZhongUser smZhongUser = (SmZhongUser) zhongUser;
        //smZhongUser.setVipAuth(sAuth);
//        return zhongUserZhongRes;

    }

    private ZhongRes<ZhongUser> invite(ZhongReq zhongReq, ZhongUser sessionZhongUser) {

        String card = zhongReq.getCard();
        boolean checked = RechargeCardUtil.checkInviteCode(card);
        if(!checked){
            return ZhongRes.fail("邀请码无效");
        }
        ZhongUser inviteUser = zhongUserService.getByCode(card, 1);
        if(inviteUser==null){
            return ZhongRes.fail("邀请码无效");
        }
       if(inviteUser.getAccount().equalsIgnoreCase(sessionZhongUser.getAccount())){
            return ZhongRes.fail("不能使用自己的邀请码");
        }
        try{
            LocalDateTime localDateTime = inviteRecordService.updateInviteRecord(card, sessionZhongUser, inviteUser);
            sessionZhongUser.setVipExpDate(localDateTime);
            redisHelper.delSmLoadSession("",  sessionZhongUser.getAccount());
            redisHelper.delSmLoadSession("",inviteUser.getAccount());
            ThreadPoolUtils.submitTask(()->{
                //异步更新
                redisHelper.smLoadSession(sessionZhongUser.getToken());
            });
        }catch (DuplicateKeyException e){
            return ZhongRes.fail("一个用户只能使用一次邀请码");
        }
        return ZhongRes.ok(sessionZhongUser);

    }

    @ApiOperation(value = "1.0 exchange人数兑换", httpMethod = "POST", notes = "1.0 exchange人数兑换", consumes = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping("exchange")
    public ZhongRes<Integer> exchange() {
        //Integer unrealizedNum = jsonObject.getInteger("unrealizedNum");
        SmZhongUser smUserInfo = ThreadLocalSession.getSmUserInfo();;//StrUtils.isNotBlank(account)?zhongUserService.getSmUser(account) :cached;
        if(smUserInfo==null){
            return VarConstant.need_login_res;
        }
        //SmZhongUser smUser = zhongUserService.getSmUser(smUserInfo.getAccount());
        redisHelper.delSmLoadSession(smUserInfo.getToken(), smUserInfo.getAccount());
        int exchange = inviteRecordService.exchange(smUserInfo, null);
        if(exchange<=0){
            return ZhongRes.fail("暂无需要兑换VIP天数");
        }
        ZhongRes ok = ZhongRes.ok();
        ok.setMsg("兑换VIP天数成功，VIP+"+exchange+"天");
        return ok;

    }

    @ApiOperation(value = "5.0 购卡列表", httpMethod = "POST", notes = "5.0 购卡列表", consumes = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping("productList")
    public ZhongRes<List<Product>> productList() {
        List<Product> products = systemConfigService.productList(true);
        return ZhongRes.ok(products);

    }


    static String jsonStr  = "{\"goods_key\":\"%s\",\"quantity\":1,\"coupon_code\":\"\",\"channel_id\":2,\"contact\":\"%s\",\"select_cards_ids\":[],\"extend\":{\"juuid\":\"%s\"}}";
    static String juuid = "vyBsMQGK5SeAYukz";
    static String tradeApi = "https://pay.ldxp.cn/shopApi/Pay/order";
    @ApiOperation(value = "5.0  生成订单并支付", httpMethod = "POST", notes = "5.0 生成订单并支付", consumes = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping("toPay")
    public ZhongRes<PayInfo> toPayLdxp(@RequestBody JSONObject jsonObject) {
        String productId = jsonObject.getString("productId");
        List<Product> products = systemConfigService.productList(false);
        Product product = products.stream().filter(o -> o.getId().equals(productId)).findFirst().orElse(null);
        if(product==null){
            return ZhongRes.fail("充值功能异常，请稍后再试-PINL");
        }
        SmZhongUser smUserInfo = ThreadLocalSession.getSmUserInfo();
        ZhongOrder zhongOrder = zhongOrderService.getHoldOne(productId, product.getVipDays(),smUserInfo.getAccount());

        if(zhongOrder==null){
            //生成tradeNo
            //JSONObject jsonObjectTrade = new JSONObject(tradeJsonObject);
            String telephone = smUserInfo.getTelephone();
            String tradePostStr = String.format(jsonStr,productId,telephone.substring(2),juuid);
            String execute = new OkHttpUtil().post(tradePostStr)
                    .url(tradeApi)
                    .retryCount(2)
                    .addHeader("Content-Type", "application/json")
                    .addHeader("User-Agent","Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Mobile Safari/537.36")
                    .addHeader("Referer", "https://pay.ldxp.cn/item/"+productId)
                    .proxySupplier(() -> proxyHelper.one())
                    .timeoutMillis(2000)
                    .execute();
            ZyantExceptionUtils.x(StrUtils.isBlank(execute),"充值功能异常-TRADE");
            JSONObject jsonObjectTrade = JSONObject.parseObject(execute);
            ZyantExceptionUtils.x(jsonObjectTrade.getIntValue("code")!=1,jsonObjectTrade.getString("msg"));
            JSONObject data = jsonObjectTrade.getJSONObject("data");
            String tradeNo = data.getString("trade_no");
            //String payurl = data.getString("payurl");
            zhongOrder = new ZhongOrder();
            zhongOrder.setOrderCode(tradeNo);
            zhongOrder.setProductId(productId);
            zhongOrder.setVipDays(product.getVipDays());
            zhongOrder.setPayAmount(data.getFloatValue("total_amount"));
            zhongOrder.setPayAccount(ThreadLocalSession.getSmUserInfo().getAccount());
            zhongOrder.setId(IdWorker.getId());
            zhongOrderService.save(zhongOrder);
            PayInfo payInfo = new PayInfo();
            payInfo.setOrderCode(tradeNo);
            payInfo.setPayUrl(jumpPayHtml+tradeNo);
            return ZhongRes.ok(payInfo);

        }
        PayInfo payInfo = new PayInfo();
        payInfo.setOrderCode(zhongOrder.getOrderCode());
        payInfo.setPayUrl(jumpPayHtml+zhongOrder.getOrderCode());
        return ZhongRes.ok(payInfo);

    }
    public static final String jumpPayHtml = "https://15133.kstore.vip/zy-html/iframe-order.html?trade_no=";

    @ApiOperation(value = "7.7  检查支付状态", httpMethod = "POST", notes = "7.7 检查支付状态", consumes = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping("checkOrderStatus")
    public ZhongRes<Integer> checkPay(@RequestBody JSONObject jsonObject) {
        SmZhongUser smUserInfo = ThreadLocalSession.getSmUserInfo();
        if(smUserInfo==null){
            return VarConstant.need_login_res;
        }
        String orderCode = jsonObject.getString("orderCode");
        Boolean paid = smurfsManager.checkLdxpOrder(orderCode);
        ThreadPoolUtils.submitTask(()->{
            if (paid) {
                smurfsManager.updateOrderStatus(orderCode, smUserInfo.getAccount());
            }else{
                LambdaUpdateWrapper<ZhongOrder> updateWrapper = zhongOrderService.getUpdateWrapper().eq(ZhongOrder::getOrderCode, orderCode)
                        .set(ZhongOrder::getUpdateTime, LocalDateTime.now());
                zhongOrderService.update(updateWrapper);
            }
        });
        return ZhongRes.ok(paid?1:0);
    }


//https://azz.net/static/pay/huotan_wap.html?order_id=ZrwQb5AsVZOivpYcK0n
    @ApiOperation(value = "5.0  生成订单并支付", httpMethod = "POST", notes = "5.0 生成订单并支付", consumes = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping("toPay_h")
    public ZhongRes<PayInfo> toPayHuotao(@RequestBody JSONObject jsonObject) {
        String productId = jsonObject.getString("productId");
        List<Product> products = systemConfigService.productList(false);
        Product product = products.stream().filter(o -> o.getId().equals(productId)).findFirst().orElse(null);
        if(product==null){
            return ZhongRes.fail("充值功能暂时关闭，请稍后再试-PINL");
        }
        SmZhongUser smUserInfo = ThreadLocalSession.getSmUserInfo();
        String payType = jsonObject.getString("payType");
        payType = "alipay";
        ZhongOrder zhongOrder = zhongOrderService.getHoldOne(productId, product.getVipDays(),smUserInfo.getAccount());
        if(zhongOrder!=null&&StrUtils.isNotBlank(zhongOrder.getOrderCode())){
            PayInfo payUrl = smurfsManager.payUrl(zhongOrder.getOrderCode(), payType);
            return ZhongRes.ok(payUrl);
        }
        //获取token
        String token = smurfsManager.orderToken(true);
        if (StrUtils.isBlank(token)){
            return ZhongRes.fail("充值功能暂时关闭,请稍后再试-ERROR");
        }
        String userId = smurfsManager.checkToken(token);
        String orderCode = smurfsManager.createOrder(productId, payType, token);
        if (StrUtils.isBlank(orderCode)){
            return ZhongRes.fail("充值功能暂时关闭,请稍后再试-OERR");
        }
        zhongOrder = new ZhongOrder();
        zhongOrder.setOrderCode(orderCode);
        zhongOrder.setProductId(productId);
        zhongOrder.setVipDays(product.getVipDays());
        zhongOrder.setPayAmount(Float.valueOf(product.getPrice()));
        zhongOrder.setPayAccount(ThreadLocalSession.getSmUserInfo().getAccount());
        zhongOrder.setId(IdWorker.getId());
        zhongOrderService.save(zhongOrder);
        PayInfo payUrl = smurfsManager.payUrl(zhongOrder.getOrderCode(), payType);
        return ZhongRes.ok(payUrl);
        //return ZhongRes.fail("充值功能暂时关闭，请稍后再试");


        //跳转支付页面


    }

    @ApiOperation(value = "7.7  检查支付状态", httpMethod = "POST", notes = "7.7 检查支付状态", consumes = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping("checkOrderStatusHuo")
    public ZhongRes<Integer> checkPayHuo(@RequestBody JSONObject jsonObject) {
        //https://xiaoamao.usells.com/api/v2/order/status?pid=jgDNJtNMQy2n
        String orderCode = jsonObject.getString("orderCode");
        SmZhongUser smUserInfo = ThreadLocalSession.getSmUserInfo();
        String execute = new OkHttpUtil().timeoutMillis(2000)
                .url("https://xiaoamao.usells.com/api/v2/order/status?pid=" + orderCode)
                .get().execute();
        Boolean paid = Optional.ofNullable(execute)
                .map(o -> JSONObject.parseObject(o))
                .map(o -> o.getJSONObject("data"))
                .map(o -> o.getBooleanValue("is_paid"))
                .orElse(false);
        //paid = paid||AperStringUtils.hitNumber(10);
        if (paid) {
            smurfsManager.updateOrderStatus(orderCode, smUserInfo.getAccount());

        }
        return ZhongRes.ok(paid?1:0);
    }




    public static void loginHuotan(String token,String productId,String payType) throws Exception {
//        Map<String, String> headerMap = new HashedMap();
//        headerMap.put("Content-Type", "application/x-www-form-urlencoded");
//        headerMap.put("referer","https://xiaoamao.usells.com/p/pG3aeJ");
//        headerMap.put("origin","https://xiaoamao.usells.com");
//        headerMap.put("user-agent","Mozilla/5.0 (Linux; Android 8.0.0; SM-G955U Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Mobile Safari/537.36");
//        String key = "xiaoamao.usells.logon";
//        String execute = new OkHttpUtil().url("https://xiaoamao.usells.com/api/v2/auth/login").retryCount(2)
//                .post("account=xiaoamao%40yopmail.com&password=123gh123&client=web")
//                .headers(headerMap).execute();
//        JSONObject jsonObject = JSONObject.parseObject(execute);
//        Integer ret = jsonObject==null?null:jsonObject.getInteger("ret");
//        JSONObject logonData = null;
//        if(Objects.equals(ret,0)){
//            logonData = jsonObject.getJSONObject("data");
//            //stringRedisTemplate.opsForValue().set("xiaoamao.usells.logon",logonData.toJSONString());
//        }else{
//            log.info("xiaoamao.usells.com login error res:{}",jsonObject);
//        }
//        token = logonData.getString("token");
//        //JSONObject cookies = logonData.getJSONObject("cookies");
//
//        String api = "https://www.huotan.com/api/v2/payment/topay/%s?type=%s&r=2";
//        api = String.format(api,prepay_id,payType);
//        execute2 = new OkHttpUtil().url(api).get()
//                .retryCount(2)
//                .post("cart="+hash)
//                .headers(headerMap).execute();
//
//        log.info("execute2:{}",execute2);
//        int a = execute2.indexOf("= \"")+3;
//        int b = execute2.indexOf(";<")-1;
//        String newApi = execute2.substring(a,b);
//        headerMap.remove("Cookie");
//        String payHtmlText = new OkHttpUtil().url(newApi).get()
//                .retryCount(2)
//                .headers(headerMap).execute();
//        log.info("newApi:{},payHtmlText:{}",newApi,payHtmlText);

        //https://www.huotan.com/api/v2/payment/topay/GWEaJC4xLPXr?type=weixin&r=2



    }

}
